﻿using Microsoft.Xna.Framework;
using RainEngine.SceneNodes;

namespace RainEngine.Controllers
{
    /// <summary>
    /// SceneNode Controlle抽象类,是所有controllers的基类
    /// </summary>
    public abstract class Controller : IController  
    {
        /// <summary>
        /// 创建一个新Controller对象
        /// </summary>        
        public Controller(RainGE engine)
        {
            this.engine = engine;
        }
        
        /// <summary>
        /// 指向引擎的引用
        /// </summary>
        protected RainGE        engine;

        /// <summary>
        /// 此对象控制的节点
        /// </summary>
        protected SceneNode    controlledNode;

        /// <summary>
        /// 表示控制器是否需要更新被控制的节点。
        /// </summary>
        internal protected bool isDirty = true;

        /// <summary>
        /// controllers主要控制逻辑 
        /// 在Controller.Update()中调用，间接由SceneNode.Update()调用
        /// 必须被派生类重写!
        /// </summary>
        /// <param name="gameTime"></param>
        public abstract void ControllerAction(GameTime gameTime);

        /// <summary>
        /// 设置控制的节点
        /// </summary>
        /// <param name="node"></param>
        public virtual void AttachNode(SceneNode node)
        {
            if (controlledNode != null)
            {
                SceneNode tmp = controlledNode;
                controlledNode = null;
                tmp.DetachController(this);
            }

            node.AttachController(this);
            controlledNode = node;
        }
        /// <summary>
        /// 移除控制的节点
        /// </summary>
        public virtual void DetachNode()
        {
            if (controlledNode != null)
            {
                SceneNode tmp = controlledNode;
                controlledNode = null;
                tmp.DetachController(this);
            }
        }        
        
        private bool isEnabled = true;        

        /// <summary>
        /// 打开/关闭控制器
        /// </summary>
        public bool Enabled
        {
            get { return isEnabled; }
            set {isEnabled = value;}            
        }
       
        /// <summary>
        /// 如果isEnabled则执行ControllerAction方法，这个方法被SceneNode.Update()调用
        /// </summary>
        /// <param name="gameTime"></param>
        public void Update(GameTime gameTime)
        {
            if (isEnabled && controlledNode!= null && engine.IsActive)
                ControllerAction(gameTime);
        }        
    }
    
}
